﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace INSTA.Concepts.TemplateMethodPattern
{
    class Program
    {
        static void Main(string[] args)
        {
            AbstractFile[] allFiles = new AbstractFile[2];

            // On crée un objet Person..
            var person = new Person()
                        {
                            Name = "toto",
                            FirstName = "titi",
                            YearOfBirth = 1954,
                            IsAdult = true
                        };


            // On ajoute quelques objets AbstractFile au tableau allFiles.
            // Notons que le type de déclaration de ces objets est "AbstractFile" mais
            // que le type effectivement affecté à ces objets est soit "DelimitedFile",
            // soit "XmlFile".
            AbstractFile file1 = new DelimitedFile(person, "Person");
            AbstractFile file2 = new XmlFile(person, "Person");

            // on stocke les deux objets dans le tableau..
            allFiles[0] = file1;
            allFiles[1] = file2;

            //  On parcourt le tableau allFiles peuplé d'objets dont le type de déclaration
            //  est AbstractFile, et l'on appelle la "Template Method" Write sur tous ces objets.
            //
            //  On constatera que, bien que le type de déclaration des objets dans le tableau 
            //  allFiles soit toujours AbstractFile, c'est l'implémentation du type d'affectation
            //  qui sera appelée sur chacun des objets (polymoprhisme standard), permettant ainsi 
            //  un traitement spécifique pour chacun de ces objets.            
            foreach (AbstractFile file in allFiles)
            {
                // Appel de la méthode "modèle" (Template Method)...
                file.Write();
            }

            // Enfin on fait afficher le contenu des deux fichiers générés dans la console.
            DumpFile("Person.csv");
            DumpFile("Person.xml");
        }

        /// <summary>
        /// Affiche le contenu du fichier spécifié dans la console.
        /// </summary>
        /// <param name="fileName">Le nom du fichier à afficher</param> 
        private static void DumpFile(string fileName)
        {
            StringBuilder sb = new StringBuilder();
            const string CRLF = "\r\n";

            sb.AppendFormat("----------------------------------------{0}", CRLF);
            sb.AppendFormat("-->{0}{1}", Path.GetFileName(fileName), CRLF);
            sb.AppendFormat("----------------------------------------{0}", CRLF);

            using (StreamReader sr = new StreamReader(fileName))
            {
                sb.Append(sr.ReadToEnd());
            }

            sb.AppendFormat("{0}----------------------------------------{0}{0}", CRLF);
            Console.WriteLine(sb.ToString());
        }
    }
}

